package ngat.oss;


import java.io.*;
import java.util.*;

import ngat.util.*;
import ngat.phase2.*;
import ngat.message.GUI_RCS.*;
import ngat.net.datalogger.*;

/** The EricPlugin is a plugin to handle fake execution of an observation supplied by Eric Saunders.
 */
public class EricsPlugin {

    String teaHost;
    int    teaPort;

    DataCampSender sender;

    public EricsPlugin() {

    }

    /** Configure the plugin from a file.*/
    public void configure(File file) throws Exception {
	ConfigurationProperties config = new ConfigurationProperties();
	config.load(new FileInputStream(file));

	teaHost = config.getProperty("tea-host");
	teaPort = config.getIntValue("tea-port");
    
	sender = new DataCampSender(new Vector(), teaHost, teaPort, 10000L);

    }

    /** Handle the execution of an Eric group.*/
    public void fakeExec(Group group) throws Exception {

	// Basically all we do is send an ObsStatusInfo and a number of ReductionInfos to the TEA.
	// Push this to a thread and put time gaps in place so they dont all arrive at once.
	// Dont want to block the scheduler's return while doing this..

	Path groupPath = new Path(group.getFullPath());

	Proposal proposal = OSS_Utilities.fetchProposal(groupPath);

	long now = System.currentTimeMillis();
	long doneTime = now;
	
	// Now mark the group as done or update its lastCompletion if its an MG.
	if (group instanceof MonitorGroup) {
	 
	    // --------------
	    // MONITOR_GROUP.
	    // --------------
	    
	    long period = ((MonitorGroup)group).getPeriod();
	    long start  = ((MonitorGroup)group).getStartDate();
	    
	    int iPeriod = 
	    (int)Math.rint( (double)(doneTime - start) /
			    (double)period);
	    
	    int cPeriod = 
	    (int)Math.rint( (double)(now - start) /
			    (double)period);
	   
	    ((MonitorGroup)group).setLastPeriod(iPeriod);
	    ((MonitorGroup)group).setLastCompleted(doneTime);
	    	    
	    // ### This should be in SCHEUDLEImpl and should be the actual time not NOW !
	    ((MonitorGroup)group).setLastScheduled(doneTime);
	     
	} else if
	    (group instanceof FixedGroup) {
	    
	    // ------------
	    // FIXED_GROUP.
	    // ------------

		group.setDone(true);
		group.setDoneDate(doneTime);
	
		Scheduling.removeFixedGroup((FixedGroup)group);

	} else {
	 	    	
	    // -------------------------
	    // GENERIC (FLEXIBLE) GROUP.
	    // -------------------------
	    
	    group.setDone(true);
	    group.setDoneDate(doneTime);
	
	}
	
	group.updateHistory(doneTime, true, 10000, "Faked execution", "-");


	// Now store the modified group info.
	OSS_Utilities.storeProposal(proposal);

        Executor executor = new Executor(group);
	executor.start();

    }

    private class Executor extends Thread {

	Group group;

	Executor(Group group) {
	    this.group = group;
	}

	public void run() {
	    
	    Iterator io = group.listAllObservations();
	    while (io.hasNext()) {

		Observation obs = (Observation)io.next();
		String obsPathName = obs.getFullPath();
		
		// Each multrun - ReductionInfo
		int nm = obs.getNumRuns();
		for (int irun = 0; irun < nm; irun++) {
		    
		    ReductionInfo info = new ReductionInfo(System.currentTimeMillis());
		    
		    info.setObsPathName(obsPathName);
		    info.setFileName("/occ/tmp/eric.fits");
		    info.setCountReducedExposures(irun);
		    
		    // These are not actually used
		    info.setSeeing(0.6);
		    info.setPhotometricity(1.0);
		    info.setSkyBrightness(1.0);
		    info.setCounts(1000);
		    info.setXpix(1024);
		    info.setYpix(1024);
		    
		    sender.dataUpdate(info);
		    
		    try { Thread.sleep(2000L);} catch (InterruptedException ix) {}
		    
		} // next multrun
		
		// At end of Obs - ObservationStatusInfo
		
		ObservationStatusInfo info = new ObservationStatusInfo(System.currentTimeMillis(),
								       obsPathName,
								       ObservationStatusInfo.COMPLETED,
								       "Observation completed");
				
		sender.dataUpdate(info);

	    }  // next obs

	} //(run)

    } // [Executor]

} // [EricPlugin]
